package com.mes.datasource.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckSQLParamsUtil {
	private static final String regString = "\\{(.*?)\\[(.*?)\\](.*?)\\}";
	private String sql = null;
	private List<Object> paramValues = null;
	
	public static CheckSQLParamsUtil getInstance() {
		return new CheckSQLParamsUtil();
	}
	
	private CheckSQLParamsUtil() {
	}
	
	public CheckSQLParamsUtil(String sql, Map<String, Object> params, String repalceWhere) {
		String querySql = sql;
		paramValues = new ArrayList<Object>();
		Map<String, List<String>> wheres = checkParams(sql, params);
		List<String> list = null;
		String where = null;
		
		for (String code : wheres.keySet()) {
			list = wheres.get(code);
			for (String w : list) {
				if (params != null && params.containsKey(code)) {
					if (w.toUpperCase().indexOf(" LIKE ") > -1) {
						where = w.replace("[" + code + "]", "'%' || ? || '%'").replace("{", "").replace("}", "");
					} else {
						where = w.replace("[" + code + "]", "?").replace("{", "").replace("}", "");
					}
				} else {
					where = repalceWhere;
				}
				querySql = querySql.replace(w, where);
			}
		}
		this.sql = querySql;
	}
	
	private Map<String, List<String>> checkParams(String sql, Map<String, Object> params) {
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		List<String> wheres = null;
		
        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(sql);
        
        if (matcher.find()) {
            matcher.reset();
            String code = null;
            String where = null;
            
            while (matcher.find()) {
            	where = matcher.group(0);
                code = matcher.group(2);
                
                wheres = map.get(code);
                if (wheres == null) {
                	wheres = new ArrayList<String>();
                	map.put(code, wheres);
                }
                wheres.add(where);
                
                if (params != null && params.containsKey(code)) {
                	paramValues.add(params.get(code));
                }
            }
        }
        return map;
    }
	
	public String getExeSQL(String sql, String repalceWhere) {
		String querySql = sql;
		Map<String, List<String>> wheres = checkParams(sql);
		List<String> list = null;
		
		for (String code : wheres.keySet()) {
			list = wheres.get(code);
			for (String w : list) {
				querySql = querySql.replace(w, repalceWhere);
			}
		}
		return querySql;
	}
	
	public Map<String, List<String>> checkParams(String sql) {
		Map<String, List<String>> map = new HashMap();
		List<String> wheres = null;
		
        Pattern pattern = Pattern.compile(regString);
        Matcher matcher = pattern.matcher(sql);
        
        if (matcher.find()) {
            matcher.reset();
            String code = null;
            String where = null;
            
            while (matcher.find()) {
            	where = matcher.group(0);
                code = matcher.group(2);
                
                wheres = map.get(code);
                if (wheres == null) {
                	wheres = new ArrayList<String>();
                	map.put(code, wheres);
                }
                wheres.add(where);
            }
        }
        return map;
    }

	public String getSql() {
		return sql;
	}

	public Object[] getParamValues() {
		return paramValues.toArray();
	}
}